package utils

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"path/filepath"

	"webpagedown3/pkg/progress"
	"webpagedown3/pkg/task"
)

func DownloadFile(downloadtask *task.DownloadTask) error {
	// 检查文件是否已存在，获取已下载的大小
	fi, err := os.Stat(downloadtask.TargetPath)
	if err == nil {
		downloadtask.CurrentSize = fi.Size()
	} else if !os.IsNotExist(err) {
		return err
	}

	// 创建请求
	req, err := http.NewRequest("GET", downloadtask.URL, nil)
	if err != nil {
		return err
	}

	// 设置User-Agent
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	//判断返回网页大小和文件大小
	if resp.ContentLength > downloadtask.CurrentSize {
		req.Header.Set("Range", fmt.Sprintf("bytes=%d-", downloadtask.CurrentSize))
	}

	// 发送请求
	resp, err = http.DefaultClient.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	// 检查响应状态
	if resp.StatusCode >= 400 {
		return fmt.Errorf("服务器返回错误: %s", resp.Status)
	}

	// 获取文件总大小
	if downloadtask.TotalSize == 0 {
		if resp.ContentLength > 0 {
			downloadtask.TotalSize = resp.ContentLength + downloadtask.CurrentSize
		} else {
			downloadtask.TotalSize = -1 // 未知大小
		}
	}

	// 确保目录存在
	if err := os.MkdirAll(filepath.Dir(downloadtask.TargetPath), 0755); err != nil {
		return err
	}

	// 创建或打开文件
	var file *os.File
	if downloadtask.CurrentSize > 0 && downloadtask.CurrentSize < downloadtask.TotalSize {
		file, err = os.OpenFile(downloadtask.TargetPath, os.O_APPEND|os.O_WRONLY, 0644)
	} else {
		file, err = os.Create(downloadtask.TargetPath)
	}
	if err != nil {
		return err
	}
	defer file.Close()

	// 创建进度条
	reader := progress.CreateProgressBar(downloadtask, resp)

	// 写入文件
	written, err := io.Copy(file, reader)
	if err != nil {
		return err
	}

	// 更新已下载大小
	downloadtask.CurrentSize += written

	// 检查是否下载完成
	if downloadtask.TotalSize > 0 && downloadtask.CurrentSize >= downloadtask.TotalSize {
		downloadtask.Completed = true
		downloadtask.Bar.Finish()
	} else if downloadtask.TotalSize == -1 {
		downloadtask.Completed = true
		downloadtask.Bar.Finish()
	} else {
		return fmt.Errorf("下载失败: %s", downloadtask.URL)
	}

	return nil
}
